/*******************************************************************
 *
 * Copyright (C), 2021-2022, LS, All rights reserved.
 *
 * Author      : 
 * Create Time : 2020-12-17
 * Version     : v0.1
 * Description : 
 *******************************************************************/
 
/*----------------------------Head file----------------------------*/
#include "user_config.h"
#include "app_display.h"
#include "app_battery.h"
#include "user_config.h"
#include "app_global_data.h"

#define APP_DISP_LOG_EN		1

#if APP_DISP_LOG_EN
#include "log.h"
#define APP_DISP_LOG		LOG_DEBUG
#else
#define APP_DISP_LOG(...)
#endif

/*----------------------------macro file---------------------------*/
#define FULL_BATT_LEVEL_NUM     3

/*----------------------------type define--------------------------*/

/*----------------------------var define---------------------------*/
static const num_seg_t num_use_seg[8] = {
    {7, 6},	 //1
    {5, 4},	 //2
    {3, 2},	 //3
    {1, 17}, //4
    {16, 15}, //5
    {14, 13},//6
    {12, 11},//7
    {10, 9},//8
};

static const uint8_t seg_char_val[] = {
    (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F),        //SEG_CHAR_0
    (SEG_B | SEG_C),                                        //SEG_CHAR_1
    (SEG_A | SEG_B | SEG_G | SEG_E | SEG_D),                //SEG_CHAR_2
    (SEG_A | SEG_B | SEG_G | SEG_C | SEG_D),                //SEG_CHAR_3
    (SEG_F | SEG_G | SEG_B | SEG_C),                        //SEG_CHAR_4
    (SEG_A | SEG_F | SEG_G | SEG_C | SEG_D),                //SEG_CHAR_5
    (SEG_A | SEG_F | SEG_E | SEG_D | SEG_C | SEG_G),        //SEG_CHAR_6
    (SEG_A | SEG_B | SEG_C),                                //SEG_CHAR_7
    (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G),//SEG_CHAR_8
    (SEG_A | SEG_F | SEG_G | SEG_B | SEG_C | SEG_D),        //SEG_CHAR_9
    (SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G),        //SEG_CHAR_A
    (SEG_A | SEG_F | SEG_E | SEG_D),                        //SEG_CHAR_C
    (SEG_A | SEG_F | SEG_G | SEG_E),                        //SEG_CHAR_F
    (SEG_A | SEG_B | SEG_G | SEG_F | SEG_E),                //SEG_CHAR_P
    (SEG_F | SEG_E | SEG_D),                                //SEG_CHAR_L
    (SEG_G | SEG_E | SEG_D | SEG_C),                        //SEG_CHAR_o
    (SEG_B | SEG_C | SEG_G | SEG_E | SEG_D),                //SEG_CHAR_d
    (SEG_E | SEG_F | SEG_A | SEG_B | SEG_C),                //SEG_CHAR_N
    (SEG_A | SEG_F | SEG_G | SEG_E | SEG_D),                //SEG_CHAR_E
    (SEG_G),                                                //SEG_CHAR_MINUS
};


static const uint8_t seg_char_val_1[] = {
    (SEG_A_1 | SEG_B_1 | SEG_C_1 | SEG_D_1 | SEG_E_1 | SEG_F_1),        //SEG_CHAR_0
    (SEG_B_1 | SEG_C_1),                                                //SEG_CHAR_1
    (SEG_A_1 | SEG_B_1 | SEG_G_1 | SEG_E_1 | SEG_D_1),                  //SEG_CHAR_2
    (SEG_A_1 | SEG_B_1 | SEG_G_1 | SEG_C_1 | SEG_D_1),                  //SEG_CHAR_3
    (SEG_F_1 | SEG_G_1 | SEG_B_1 | SEG_C_1),                            //SEG_CHAR_4
    (SEG_A_1 | SEG_F_1 | SEG_G_1 | SEG_C_1 | SEG_D_1),                  //SEG_CHAR_5
    (SEG_A_1 | SEG_F_1 | SEG_E_1 | SEG_D_1 | SEG_C_1 | SEG_G_1),        //SEG_CHAR_6
    (SEG_A_1 | SEG_B_1 | SEG_C_1),                                      //SEG_CHAR_7
    (SEG_A_1 | SEG_B_1 | SEG_C_1 | SEG_D_1 | SEG_E_1 | SEG_F_1 | SEG_G_1),//SEG_CHAR_8
    (SEG_A_1 | SEG_F_1 | SEG_G_1 | SEG_B_1 | SEG_C_1 | SEG_D_1),        //SEG_CHAR_9
    (SEG_A_1 | SEG_B_1 | SEG_C_1 | SEG_E_1 | SEG_F_1 | SEG_G_1),        //SEG_CHAR_A
    (SEG_A_1 | SEG_F_1 | SEG_E_1 | SEG_D_1),                            //SEG_CHAR_C
    (SEG_A_1 | SEG_F_1 | SEG_G_1 | SEG_E_1),                            //SEG_CHAR_F
    (SEG_A_1 | SEG_B_1 | SEG_G_1 | SEG_F_1 | SEG_E_1),                  //SEG_CHAR_P
    (SEG_F_1 | SEG_E_1 | SEG_D_1),                                      //SEG_CHAR_L
    (SEG_G_1 | SEG_E_1 | SEG_D_1 | SEG_C_1),                            //SEG_CHAR_o
    (SEG_B_1 | SEG_C_1 | SEG_G_1 | SEG_E_1 | SEG_D_1),                  //SEG_CHAR_d
    (SEG_E_1 | SEG_F_1 | SEG_A_1 | SEG_B_1 | SEG_C_1),                  //SEG_CHAR_N
    (SEG_A_1 | SEG_F_1 | SEG_G_1 | SEG_E_1 | SEG_D_1),                  //SEG_CHAR_E
    (SEG_G_1),                                                          //SEG_CHAR_MINUS
};


//TM1621C, SEG6~12 / SEG20~25 is empty, fix PCB line sequence
static const uint8_t seg_index_conv_tbl[SEGMENT_MAX_NUM] = {
    0,   //SEG_0
    1,   //SEG_1
    2,   //SEG_2
    3,   //SEG_3
    4,   //SEG_4
    5,  //SEG_5
    6,  //SEG_6
    7,  //SEG_7
    8,  //SEG_8
    9,  //SEG_9
    10,  //SEG_10
    11,  //SEG_11
    12,  //SEG_12
    13,   //SEG_13
    14,   //SEG_14
    15,   //SEG_15
    16,   //SEG_16
    17,   //SEG_17
};

//LCD Pin num <-> TM1621 seg num
static const icon_seg_t icon_mask[12] = {
    {11, 0x08},        //ICON_BT
    {8, 0x08},         //ICON_BAT0
    {8, 0x02},         //ICON_BAT1
    {8, 0x01},         //ICON_BAT2
    {8, 0x04},         //ICON_BAT3
    {13, 0x08},        //ICON_MODE_FREE
    {9, 0x08},         //ICON_MODE_COUNTDOWN_NUM
    {7, 0x08},         //ICON_MODE_COUNTDOWN_TIME
    {5, 0x08},         //ICON_DOT_MINS
    {1, 0x08},         //ICON_DOT_SECS
};

uint8_t disp_buffer[SEGMENT_MAX_NUM/2];

/*-------------------------func declaration------------------------*/

/*-----------------------------------------------------------------*/

void app_disp_hw_deinit(void)
{
    hal_disp_sleep_enable();
    hal_disp_hw_deinit();
}


void app_disp_hw_init(void)
{
    hal_disp_hw_init();
    hal_disp_drv_init();
    hal_disp_cmd_init();
}

void app_disp_all_pixel(void)
{
    memset(disp_buffer, 0xFF, sizeof(disp_buffer));
    app_disp_update();
}

void app_disp_clear(void)
{
    memset(disp_buffer, 0, sizeof(disp_buffer));
}


static void app_disp_char_set(uint8_t num_no, uint8_t char_enum)
{
    if(num_no > NUM_NO_8)
        return;

    if(char_enum >= SEG_CHAR_MAX)
        return;

    uint8_t mask = 0;
    uint8_t val = CHAR_NULL;
    uint8_t idx1 = seg_index_conv_tbl[num_use_seg[num_no].seg1];
    uint8_t idx2 = seg_index_conv_tbl[num_use_seg[num_no].seg2];
    //APP_DISP_LOG("idx: %d, num: %d\n", index, disp_num);
    //APP_DISP_LOG("idx1: %d, idx2: %d\n", idx1, idx2);

    if(num_no <= NUM_NO_4) {
        if(CHAR_NULL != char_enum) {
            val = seg_char_val[char_enum];
        }
        
        if((idx1 % 2 ) == 0) {
            idx1 = idx1 / 2;
            mask = disp_buffer[idx1] & NUM_MASK1;
            disp_buffer[idx1] = (disp_buffer[idx1]&0xF0) | (val&0x0F) | mask;
        }
        else {
            idx1 = idx1 / 2;
            mask = disp_buffer[idx1] & NUM_MASK2;
            disp_buffer[idx1] = (disp_buffer[idx1]&0x0F) | (val&0xF0) | mask;
        }
        
        if((idx2 % 2 ) == 0) {
            idx2 = idx2 / 2;
            disp_buffer[idx2] = (disp_buffer[idx2]&0xF0) | (val&0x0F);
        }
        else {
            idx2 = idx2 / 2;
            if(NUM_NO_4 == num_no) {
                disp_buffer[idx2] = (disp_buffer[idx2]&0x0F) | ((val&0x0F) << 4);
            }
            else {
                disp_buffer[idx2] = (disp_buffer[idx2]&0x0F) | (val&0xF0);
            }
        }
    }
    else {
        if(CHAR_NULL != char_enum) {
            val = seg_char_val_1[char_enum];
        }
        
        if((idx1 % 2 ) == 0) {
            idx1 = idx1 / 2;
            disp_buffer[idx1] = (disp_buffer[idx1]&0xF0) | (val&0x0F);
        }
        else {
            idx1 = idx1 / 2;
            disp_buffer[idx1] = (disp_buffer[idx1]&0x0F) | (val&0xF0);
        }
        
        if((idx2 % 2 ) == 0) {
            idx2 = idx2 / 2;
            mask = disp_buffer[idx2] & NUM_MASK1;
            disp_buffer[idx2] = (disp_buffer[idx2]&0xF0) | (val&0x0F) | mask;
        }
        else {
            idx2 = idx2 / 2;
            mask = disp_buffer[idx2] & NUM_MASK2;
            disp_buffer[idx2] = (disp_buffer[idx2]&0x0F) | (val&0xF0) | mask;
        }
    }
    
    //APP_DISP_LOG("buf: %x, %x\n", disp_buffer[idx1], disp_buffer[idx2]);
}



void app_disp_icon_set(uint8_t icon)
{
    if(icon >= ICON_MAX)
        return;

    uint8_t index = seg_index_conv_tbl[icon_mask[icon].seg_num];
    uint8_t high = index % 2;
    if(index > 0) {
        index = index / 2;
    }
    
    if(high) {
        disp_buffer[index] |= (icon_mask[icon].mask << 4);
    }
    else {
        disp_buffer[index] |= icon_mask[icon].mask;
    }
}

void app_disp_icon_clear(uint8_t icon)
{
    if(icon >= ICON_MAX)
        return;

    uint8_t index = seg_index_conv_tbl[icon_mask[icon].seg_num];
    uint8_t high = index % 2;
    if(index > 0) {
        index = index / 2;
    }
    
    if(high) {
        disp_buffer[index] &= ~(icon_mask[icon].mask << 4);
    }
    else {
        disp_buffer[index] &= ~icon_mask[icon].mask;
    }
}


void app_disp_update(void)
{
    if(false == hal_disp_init_state_get())
        return;

    hal_disp_write_disp_buffer(disp_buffer, sizeof(disp_buffer));
}


static void app_disp_skip_cnt_clear(void)
{
    for(uint8_t i=0;i<4;i++) {
        app_disp_char_set(NUM_NO_5+i, CHAR_NULL);
    }
}

static void app_disp_skip_used_time_clear(void)
{
    for(uint8_t i=0;i<4;i++) {
        app_disp_char_set(NUM_NO_1+i, CHAR_NULL);
    }
    app_disp_icon_clear(ICON_DOT_MINS);
    app_disp_icon_clear(ICON_DOT_SECS);
}

void app_disp_bt_icon(void)
{
    if(g_app_data.sys.state.ble_conn) {
        app_disp_icon_set(ICON_BT);
    }
    else {
        app_disp_icon_clear(ICON_BT);
    }
}


void app_disp_batt_lo(void)
{
    app_disp_char_set(NUM_NO_7, SEG_CHAR_L);
    app_disp_char_set(NUM_NO_6, SEG_CHAR_o);
}

void app_disp_batt_state(uint8_t level)
{
    app_disp_icon_set(ICON_BAT0);
    app_disp_icon_clear(ICON_BAT1);
    app_disp_icon_clear(ICON_BAT2);
    app_disp_icon_clear(ICON_BAT3);

    if(level > 0) {
        app_disp_icon_set(ICON_BAT1);
    }
    if(level > 1) {
        app_disp_icon_set(ICON_BAT2);
    }
    if(level > 2) {
        app_disp_icon_set(ICON_BAT3);
    }
}


static void app_disp_skip_count(uint16_t num)
{
    uint8_t disp_num[4] = {0};
    uint16_t skip_num = num;

    if(skip_num > DISP_SKIP_CNT_MAX_NUM)
        skip_num = DISP_SKIP_CNT_MAX_NUM;

    disp_num[3] = skip_num%10;
    disp_num[2] = (skip_num/10)%10;
    disp_num[1] = (skip_num/100)%10;
    disp_num[0] = skip_num/1000;

//    app_disp_icon_set(ICON_SKIP_CNT);
    app_disp_char_set(NUM_NO_8, disp_num[0]);
    app_disp_char_set(NUM_NO_7, disp_num[1]);
    app_disp_char_set(NUM_NO_6, disp_num[2]);
    app_disp_char_set(NUM_NO_5, disp_num[3]);
}

void app_disp_skip_used_time(uint16_t secs)
{
    uint16_t skip_secs = secs;
    uint8_t minutes = 0, seconds = 0;

    if(skip_secs > DISP_SKIP_SEC_MAX_NUM)
        skip_secs = DISP_SKIP_SEC_MAX_NUM;

    minutes = skip_secs/60;
    seconds = skip_secs%60;

    app_disp_char_set(NUM_NO_1, minutes/10);
    app_disp_char_set(NUM_NO_2, minutes%10);
    app_disp_char_set(NUM_NO_3, seconds/10);
    app_disp_char_set(NUM_NO_4, seconds%10);
//    app_disp_icon_set(ICON_SKIP_TIME);
    app_disp_icon_set(ICON_DOT_MINS);
    app_disp_icon_set(ICON_DOT_SECS);
}

void app_disp_skip_data(void)
{
    uint8_t skip_mode = g_app_data.tmp.skip.mode;
    uint16_t total_cnts = g_app_data.tmp.skip.skip_cnt_sum;
    uint16_t total_secs = g_app_data.tmp.skip.skip_sec_sum;

    uint16_t countdown_time = g_app_data.user.cnt_down_secs;
    uint16_t countdown_num = g_app_data.user.cnt_down_jumps;

    if(skip_mode > SKIP_MODE_MAX)
        return;

    if(SKIP_MODE_RANDOM == skip_mode) {
        app_disp_icon_set(ICON_MODE_FREE);
#if(LEIJISHU == 1)
        //app_disp_icon_set(ICON_MODE_COUNTDOWN_TIME);
        //app_disp_icon_set(ICON_MODE_COUNTDOWN_NUM);
#endif
        app_disp_skip_count(total_cnts);
        app_disp_skip_used_time(total_secs);
    }
    else if(SKIP_MODE_TIME == skip_mode) {
        app_disp_icon_set(ICON_MODE_COUNTDOWN_TIME);
        app_disp_skip_count(total_cnts);
        uint16_t sec = 0;
        if(countdown_time > total_secs) {
            sec = countdown_time - total_secs;
        }
        app_disp_skip_used_time(sec);
    }
    else if(SKIP_MODE_COUNT == skip_mode) {
        app_disp_icon_set(ICON_MODE_COUNTDOWN_NUM);
        uint16_t cnt = 0;
        if(countdown_num > total_cnts) {
            cnt = countdown_num - total_cnts;
        }
        app_disp_skip_count(cnt);
        app_disp_skip_used_time(total_secs);
    }
}

void app_disp_skip_data_flash(uint8_t time_cnt)
{
    uint8_t skip_mode = g_app_data.tmp.skip.mode;
    uint16_t total_cnts = g_app_data.tmp.skip.skip_cnt_sum;
    uint16_t total_secs = g_app_data.tmp.skip.skip_sec_sum;

    if(SKIP_MODE_TIME == skip_mode) {
        if((time_cnt%2) == 0) {
            app_disp_skip_count(total_cnts);
        }
        else {
            app_disp_skip_cnt_clear();
        }
    }
    else if(SKIP_MODE_COUNT == skip_mode) {
        if((time_cnt%2) == 0) {
            app_disp_skip_used_time(total_secs);
        }
        else {
            app_disp_skip_used_time_clear();
        }
    }
}

void app_disp_cnt_down_start_secs(uint16_t num)
{
    uint8_t disp_num[4] = {0};
    uint16_t secs = num;

    if(secs > START_SKIP_SECS_MAX_VAL)
        secs = START_SKIP_SECS_MAX_VAL;

    disp_num[3] = secs%10;
    disp_num[2] = (secs/10)%10;
    //disp_num[1] = (secs/100)%10;
    //disp_num[0] = secs/1000;

    if(secs < 10) {
        app_disp_char_set(NUM_NO_2, 0);
        app_disp_char_set(NUM_NO_3, disp_num[3]);
    }
    else if(secs < 100) {
        app_disp_char_set(NUM_NO_2, disp_num[2]);
        app_disp_char_set(NUM_NO_3, disp_num[3]);
    }
    /*else if(secs < 1000) {
        app_disp_char_set(NUM_NO_2, disp_num[1]);
        app_disp_char_set(NUM_NO_3, disp_num[2]);
        app_disp_char_set(NUM_NO_4, disp_num[3]);
    }
    else {
        for(uint8_t i=0;i<sizeof(disp_num);i++) {
            app_disp_char_set(NUM_NO_1 + i, disp_num[i]);
        }
    }*/
}

#if(DEV_MAC_BURN_ENABLE)
void app_disp_ble_icon_flash(bool reset)
{
    static bool ble_icon_show = true;

    if(reset) {
        ble_icon_show = true;
    }

    if(ble_icon_show) {
        app_disp_icon_set(ICON_BT);
        ble_icon_show = false;
    }
    else {
        app_disp_icon_clear(ICON_BT);
        ble_icon_show = true;
    }
}
#endif


void app_disp_low_bat_icon_flash(bool reset)
{
	static bool bat_icon_show = true;

	if(reset) {
		bat_icon_show = true;
	}

	if(bat_icon_show) {
		app_disp_batt_state(0);
		bat_icon_show = false;
	}
	else {
		app_disp_batt_state(0);
		app_disp_icon_clear(ICON_BAT0);
		bat_icon_show = true;
	}
}

void app_disp_charge_state(bool clear)
{
	static uint8_t lvl = 0;
	uint8_t init_lvl = app_charging_batt_level_get();

	if(clear) {
		lvl = init_lvl;
	}

	app_disp_batt_state(lvl);
	if(lvl < FULL_BATT_LEVEL_NUM) {
		lvl++;
	}
	else {
		lvl = init_lvl;
	}
}

void app_disp_batt_icon(void)
{
    if(BATT_STATE_LOWBAT_WARN == g_app_data.batt.state)
        return;

	uint8_t batt_lvl = app_discharge_batt_level_get();
	app_disp_batt_state(batt_lvl);
}


void app_disp_pass(void)
{
    app_disp_char_set(NUM_NO_8, SEG_CHAR_P);
    app_disp_char_set(NUM_NO_7, SEG_CHAR_A);
    app_disp_char_set(NUM_NO_6, SEG_CHAR_5);
    app_disp_char_set(NUM_NO_5, SEG_CHAR_5);
}

void app_disp_done(void)
{
    app_disp_char_set(NUM_NO_8, SEG_CHAR_d);
    app_disp_char_set(NUM_NO_7, SEG_CHAR_0);
    app_disp_char_set(NUM_NO_6, SEG_CHAR_N);
    app_disp_char_set(NUM_NO_5, SEG_CHAR_E);
}

void app_disp_fail(void)
{
    app_disp_char_set(NUM_NO_8, SEG_CHAR_F);
    app_disp_char_set(NUM_NO_7, SEG_CHAR_A);
    app_disp_char_set(NUM_NO_6, SEG_CHAR_1);
    app_disp_char_set(NUM_NO_5, SEG_CHAR_L);
}


void app_disp_ota_ing(uint8_t cnt)
{
    app_disp_char_set(NUM_NO_8, CHAR_NULL);
    app_disp_char_set(NUM_NO_7, CHAR_NULL);
    app_disp_char_set(NUM_NO_6, CHAR_NULL);
    app_disp_char_set(NUM_NO_5, CHAR_NULL);
	
	if(cnt > 3)
		return;
	
    app_disp_char_set(NUM_NO_8 - cnt, SEG_CHAR_MINUS);
}


#if(DEV_MAC_BURN_ENABLE)
void app_disp_burn_ing(void)
{
    app_disp_char_set(NUM_NO_8, SEG_CHAR_MINUS);
    app_disp_char_set(NUM_NO_7, SEG_CHAR_MINUS);
    app_disp_char_set(NUM_NO_6, SEG_CHAR_MINUS);
    app_disp_char_set(NUM_NO_5, SEG_CHAR_MINUS);
}


void app_disp_sn(uint8_t *sn, uint8_t len)
{
	if(DEV_SN_NUM != len)
		return;

	for(uint8_t i=0;i<DEV_SN_NUM/2;i++) {
		app_disp_char_set(NUM_NO_8 - i, sn[i]);
	}
	for(uint8_t i=0;i<DEV_SN_NUM/2;i++) {
		app_disp_char_set(NUM_NO_1 + i, sn[i+(DEV_SN_NUM/2)]);
	}
}

#endif



#if(LEIJISHU)

static void app_disp_seg_val_set(uint8_t num_no, uint8_t seg_val)
{
    if(num_no > NUM_NO_8)
        return;

    uint8_t mask = 0;
    uint8_t val = CHAR_NULL;
    uint8_t idx1 = seg_index_conv_tbl[num_use_seg[num_no].seg1];
    uint8_t idx2 = seg_index_conv_tbl[num_use_seg[num_no].seg2];
    //APP_DISP_LOG("idx: %d, num: %d\n", index, disp_num);
    //APP_DISP_LOG("idx1: %d, idx2: %d\n", idx1, idx2);
    
    val = seg_val;

    if(num_no <= NUM_NO_4) {
        if((idx1 % 2 ) == 0) {
            idx1 = idx1 / 2;
            mask = disp_buffer[idx1] & NUM_MASK1;
            disp_buffer[idx1] = (disp_buffer[idx1]&0xF0) | (val&0x0F) | mask;
        }
        else {
            idx1 = idx1 / 2;
            mask = disp_buffer[idx1] & NUM_MASK2;
            disp_buffer[idx1] = (disp_buffer[idx1]&0x0F) | (val&0xF0) | mask;
        }
        
        if((idx2 % 2 ) == 0) {
            idx2 = idx2 / 2;
            disp_buffer[idx2] = (disp_buffer[idx2]&0xF0) | (val&0x0F);
        }
        else {
            idx2 = idx2 / 2;
            if(NUM_NO_4 == num_no) {
                disp_buffer[idx2] = (disp_buffer[idx2]&0x0F) | ((val&0x0F) << 4);
            }
            else {
                disp_buffer[idx2] = (disp_buffer[idx2]&0x0F) | (val&0xF0);
            }
        }
    }
    else {
        if((idx1 % 2 ) == 0) {
            idx1 = idx1 / 2;
            disp_buffer[idx1] = (disp_buffer[idx1]&0xF0) | (val&0x0F);
        }
        else {
            idx1 = idx1 / 2;
            disp_buffer[idx1] = (disp_buffer[idx1]&0x0F) | (val&0xF0);
        }
        
        if((idx2 % 2 ) == 0) {
            idx2 = idx2 / 2;
            mask = disp_buffer[idx2] & NUM_MASK1;
            disp_buffer[idx2] = (disp_buffer[idx2]&0xF0) | (val&0x0F) | mask;
        }
        else {
            idx2 = idx2 / 2;
            mask = disp_buffer[idx2] & NUM_MASK2;
            disp_buffer[idx2] = (disp_buffer[idx2]&0x0F) | (val&0xF0) | mask;
        }
    }
    
    //APP_DISP_LOG("buf: %x, %x\n", disp_buffer[idx1], disp_buffer[idx2]);
}

void app_disp_loop(bool reset)
{
    static uint8_t loop_cnt = 0;
    
    if(loop_cnt < 11) {
        loop_cnt++;
    }
    else {
        loop_cnt = 0;
    }
    
    if(reset) {
        loop_cnt = 0;
    }
    
    app_disp_seg_val_set(NUM_NO_1, SEG_A | SEG_E | SEG_F | SEG_D);
    app_disp_seg_val_set(NUM_NO_2, SEG_A | SEG_D);
    app_disp_seg_val_set(NUM_NO_3, SEG_A | SEG_D);
    app_disp_seg_val_set(NUM_NO_4, SEG_A | SEG_B | SEG_C | SEG_D);
    
    app_disp_seg_val_set(NUM_NO_5, SEG_A_1 | SEG_B_1 | SEG_C_1 | SEG_D_1);
    app_disp_seg_val_set(NUM_NO_6, SEG_A_1 | SEG_D_1);
    app_disp_seg_val_set(NUM_NO_7, SEG_A_1 | SEG_D_1);
    app_disp_seg_val_set(NUM_NO_8, SEG_A_1 | SEG_E_1 | SEG_F_1 | SEG_D_1);
    
    switch(loop_cnt)
    {
        case 0: {
            app_disp_seg_val_set(NUM_NO_1, SEG_E | SEG_F | SEG_D);
            app_disp_seg_val_set(NUM_NO_2, SEG_D);
            app_disp_seg_val_set(NUM_NO_8, SEG_E_1 | SEG_F_1 | SEG_D_1);
            app_disp_seg_val_set(NUM_NO_7, SEG_D_1);
        } break;
        case 1: {
            app_disp_seg_val_set(NUM_NO_2, SEG_D);
            app_disp_seg_val_set(NUM_NO_3, SEG_D);
            app_disp_seg_val_set(NUM_NO_7, SEG_D_1);
            app_disp_seg_val_set(NUM_NO_6, SEG_D_1);
        } break;
        case 2: {
            app_disp_seg_val_set(NUM_NO_3, SEG_D);
            app_disp_seg_val_set(NUM_NO_4, SEG_B | SEG_C | SEG_D);
            app_disp_seg_val_set(NUM_NO_6, SEG_D_1);
            app_disp_seg_val_set(NUM_NO_5, SEG_B_1 | SEG_C_1 | SEG_D_1);
        } break;
        case 3: {
            app_disp_seg_val_set(NUM_NO_4, SEG_C | SEG_D);
            app_disp_seg_val_set(NUM_NO_5, SEG_C_1 | SEG_D_1);
        } break;
        
        case 4: {
            app_disp_seg_val_set(NUM_NO_4, SEG_A | SEG_D);
            app_disp_seg_val_set(NUM_NO_5, SEG_A_1 | SEG_D_1);
        } break;
        case 5: {
            app_disp_seg_val_set(NUM_NO_4, SEG_A | SEG_B);
            app_disp_seg_val_set(NUM_NO_5, SEG_A_1 | SEG_B_1);
        } break;
        
        case 6:{
            app_disp_seg_val_set(NUM_NO_4, SEG_A | SEG_B | SEG_C);
            app_disp_seg_val_set(NUM_NO_3, SEG_A);
            app_disp_seg_val_set(NUM_NO_5, SEG_A_1 | SEG_B_1 | SEG_C_1);
            app_disp_seg_val_set(NUM_NO_6, SEG_A_1);
        } break;
        case 7:{
            app_disp_seg_val_set(NUM_NO_3, SEG_A);
            app_disp_seg_val_set(NUM_NO_2, SEG_A);
            app_disp_seg_val_set(NUM_NO_6, SEG_A_1);
            app_disp_seg_val_set(NUM_NO_7, SEG_A_1);
        } break;
        case 8:{
            app_disp_seg_val_set(NUM_NO_2, SEG_A);
            app_disp_seg_val_set(NUM_NO_1, SEG_A | SEG_E | SEG_F);
            app_disp_seg_val_set(NUM_NO_7, SEG_A_1);
            app_disp_seg_val_set(NUM_NO_8, SEG_A_1 | SEG_E_1 | SEG_F_1);
        } break;
        case 9: {
            app_disp_seg_val_set(NUM_NO_1, SEG_A | SEG_F);
            app_disp_seg_val_set(NUM_NO_8, SEG_A_1 | SEG_F_1);
        } break;
        
        case 10: {
            app_disp_seg_val_set(NUM_NO_1, SEG_A | SEG_D);
            app_disp_seg_val_set(NUM_NO_8, SEG_A_1 | SEG_D_1);
        } break;
        
        case 11: {
            app_disp_seg_val_set(NUM_NO_1, SEG_E | SEG_D);
            app_disp_seg_val_set(NUM_NO_8, SEG_E_1 | SEG_D_1);
        } break;
        
        default:
            break;
    }
}
#endif



#if 0
void app_display_test(void)
{
    app_disp_hw_init();
    app_disp_backlight_set(true);
    
    app_disp_all_pixel();
    app_disp_update();
    app_delay_ms(1000);
    
    app_disp_clear();
    
    /*for(int i=0;i<ICON_MAX;i++) {
        app_disp_icon_set(i);
        app_disp_update();
        app_delay_ms(1000);
        app_disp_icon_clear(i);
        app_disp_update();
    }*/
    
    /*for(int i=0;i<ICON_MAX;i++) {
        app_disp_icon_set(i);
    }
    
    for(int i=0;i<=NUM_NO_8;i++)
    {
        for(int j=0;j<10;j++) {
            app_disp_char_set(NUM_NO_1+i, j);
            app_disp_update();
            app_delay_ms(1000);
        }
    }*/
    
    
    /*app_disp_skip_used_time(12*60+34);
    app_disp_skip_count(1234);
    app_disp_update();
    app_delay_ms(2000);
    
    app_disp_clear();
    app_disp_batt_lo();
    app_disp_update();
    app_delay_ms(2000);
    
    app_disp_clear();
    app_disp_pass();
    app_disp_update();
    app_delay_ms(2000);
    
    app_disp_clear();
    app_disp_fail();
    app_disp_update();
    app_delay_ms(2000);
    
    app_disp_clear();
    app_disp_done();
    app_disp_update();
    app_delay_ms(2000);
    
    app_disp_clear();
    app_disp_ota_ing(0);
    app_disp_ota_ing(1);
    app_disp_ota_ing(2);
    app_disp_ota_ing(3);
    app_disp_update();
    app_delay_ms(2000);*/
}
#endif
